package org.abc.fund.service.dataSourceCollection;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.abc.fund.entity.funds.FundAnnouncement;
import org.abc.fund.repository.funds.FundAnnouncementRepository;
import org.abc.fund.repository.funds.FundBasicInfoRepository;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.abc.fund.entity.funds.FundHolding;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class FundAnnouncementService {
    private final FundBasicInfoRepository fundBasicInfoRepository;
    private final FundAnnouncementRepository fundAnnouncementRepository;
    private final FundAnnouncementCrawler crawler;

    // 批量获取所有数据库中已有基金的公告（默认获取最新一年）
    @Transactional
    public void fetchAllAnnouncements() {
        fetchAnnouncementsSince(LocalDate.now().minusYears(1), "年度更新");
    }
    // 季度更新 - 获取最近6个月的公告
    @Transactional
    public void fetchQuarterlyAnnouncements() {
        fetchAnnouncementsSince(LocalDate.now().minusMonths(6), "季度更新");
    }
    // 半年度更新 - 获取最近1年的公告
    @Transactional
    public void fetchSemiAnnualAnnouncements() {
        fetchAnnouncementsSince(LocalDate.now().minusYears(1), "半年度更新");
    }
    // 重大事件更新 - 只获取重大事件类型的公告
    @Transactional
    public void fetchImportantEventsAnnouncements() {
        LocalDate threeMonthsAgo = LocalDate.now().minusMonths(3);
        List<String> codes = fundBasicInfoRepository.getAllFundCodes();
        int totalProcessed = 0;
        int importantEventsCount = 0;
        for (String code : codes) {
            try {
                List<FundAnnouncement> announcements = crawler.fetchFundAnnouncements(code, threeMonthsAgo);
                for (FundAnnouncement ann : announcements) {
                    if (isImportantEvent(ann.getCategory())) {
                        saveOrUpdateAnnouncement(ann);
                        importantEventsCount++;
                    }
                }
                totalProcessed++;
            } catch (Exception e) {
                log.error("重大事件更新 - 基金 {} 处理失败：{}", code, e.getMessage());
            }
        }
        log.info("重大事件更新完成：处理 {} 支基金，发现 {} 条重大事件公告",
                totalProcessed, importantEventsCount);
    }

    //通用方法：获取指定日期之后的公告
    @Transactional
    public void fetchAnnouncementsSince(LocalDate sinceDate, String updateType) {
        List<String> codes = fundBasicInfoRepository.getAllFundCodes();
        log.info("开始{}，获取 {} 之后的公告，共 {} 支基金",
                updateType, sinceDate, codes.size());
        int totalSaved = 0;
        int totalUpdated = 0;

        for (String code : codes) {
            System.out.println(">>> " + updateType + " - 获取基金公告：" + code);
            List<FundAnnouncement> list = crawler.fetchFundAnnouncements(code, sinceDate);
            for (FundAnnouncement ann : list) {
                boolean isNew = saveOrUpdateAnnouncement(ann);
                if (isNew) {
                    totalSaved++;
                } else {
                    totalUpdated++;
                }
            }
        }
        log.info("{}完成：新增 {} 条公告，更新 {} 条公告", updateType, totalSaved, totalUpdated);
    }

    //数据清理 - 清理2年前的旧数据
    @Transactional
    public void cleanupOldAnnouncements() {
        LocalDate twoYearsAgo = LocalDate.now().minusYears(2);
        log.info("开始清理 {} 之前的旧公告数据", twoYearsAgo);
        int deletedCount = fundAnnouncementRepository.deleteByPublishDateBefore(twoYearsAgo);
        log.info("数据清理完成：删除 {} 条过期公告", deletedCount);
    }

    //判断是否为重大事件公告
    private boolean isImportantEvent(String category) {
        return category != null && (
                category.contains("基金经理变更") ||
                        category.contains("分红公告") ||
                        category.contains("暂停申购") ||
                        category.contains("暂停赎回") ||
                        category.contains("恢复申购") ||
                        category.contains("恢复赎回") ||
                        category.contains("份额折算") ||
                        category.contains("托管人") ||
                        category.contains("管理人变更")
        );
    }

    //保存或更新公告
    private boolean saveOrUpdateAnnouncement(FundAnnouncement ann) {
        return fundAnnouncementRepository
                .findFirstByFundCodeAndPublishDateAndTitle(
                        ann.getFundCode(),
                        ann.getPublishDate(),
                        ann.getTitle())
                .map(existing -> {
                    if (needsContentUpdate(existing, ann)) {
                        existing.setContent(ann.getContent());
                        existing.setCategory(ann.getCategory());
                        existing.setSourceUrl(ann.getSourceUrl());
                        fundAnnouncementRepository.save(existing);
                        return false; // 表示更新
                    }
                    return false; // 无需更新
                })
                .orElseGet(() -> {
                    System.out.println("保存公告："
                            + ann.getFundCode() + " | "
                            + ann.getPublishDate() + " | "
                            + ann.getTitle() + " | "
                            + ann.getCategory());
                    fundAnnouncementRepository.save(ann);
                    return true; // 表示新增
                });
    }

    // 判断是否更新文本内容
    private boolean needsContentUpdate(FundAnnouncement existing, FundAnnouncement latest) {
        if (existing == null || latest == null) {
            return false;
        }
        String currentContent = existing.getContent();
        String newContent = latest.getContent();
        return (currentContent == null || currentContent.isBlank())
                && newContent != null && !newContent.isBlank();
    }
}